/* Copyright (c) 2012 William Steven Knauer
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.williamknauer.android.yagol;

import android.content.Context;
import android.content.SharedPreferences;
import android.opengl.GLSurfaceView;
import android.preference.PreferenceManager;
import android.view.MotionEvent;
import android.widget.Toast;

import com.williamknauer.android.multitouchdetector.MultitouchDetector;
import com.williamknauer.android.multitouchdetector.SimpleMultitouchListener;

/**
 * A {@link GLSurfaceView} for drawing the game. Creates a {@link Renderer} to
 * update the screen and uses a {@link MultitouchDetector} to handle touch
 * input.
 * 
 * @author William S Knauer <knauerw1@gmail.com>
 * @version 2012.0111
 */
public class GameDelegate extends GLSurfaceView {
	private GameRenderer2 mGameRenderer;
	private MultitouchDetector mMultitouchDetector;
	private GameModel mGameModel;

	private GameUpdater mUpdaterThread = new GameUpdater(0) {

		@Override
		protected void update() {
			mGameModel.update();
		};

	};

	private SimpleMultitouchListener mMultitouchListener = new SimpleMultitouchListener() {

		@Override
		public boolean onMultiDrag(float x1, float y1, float x2, float y2, float focusX,
				float focusY, float dx, float dy) {
			return onSingleDrag(focusX, focusY, dx, dy);
		}

		@Override
		public boolean onScale(float x1, float y1, float x2, float y2, float focusX, float focusY,
				float scale) {
			return mGameRenderer.handleScale(focusX, focusY, scale);
		}

		@Override
		public boolean onSingleDrag(float x, float y, float dx, float dy) {
			return mGameRenderer.handleScroll(x, y, dx, dy);
		}

		@Override
		public boolean onSingleTap(float x, float y) {
			if (mUpdaterThread.isPaused()) {
				return mGameRenderer.handleSingleTap(x, y);
			} else {
				/*
				 * Pause the game on single tap if game is running.
				 */
				mUpdaterThread.pause();
				return true;
			}
		}

	};

	public boolean onOptionsItemSelected(int itemId) {
		switch (itemId) {
		case R.id.menu_gameao_playpause:
			if (mUpdaterThread.isPaused()) {
				mGameModel.pushUndo();
				mUpdaterThread.play();
			} else {
				mUpdaterThread.pause();
			}
			return true;
		case R.id.menu_gameao_clear:
			mGameModel.pushUndo();
			mGameModel.clear();
			return true;
		case R.id.menu_gameao_step:
			mUpdaterThread.pause();
			mGameModel.pushUndo();
			mGameModel.update();
			return true;
		case R.id.menu_gameao_reset:
			mUpdaterThread.pause();
			mGameModel.popUndo();
			return true;
		default:
			Toast.makeText(getContext(), "Feature not yet implemented.", Toast.LENGTH_SHORT).show();
			return true;
		}
	}

	public GameDelegate(Context context, GameModel gameModel) {
		super(context);
		mGameModel = gameModel;
		mGameRenderer = new GameRenderer2(gameModel, context);
		mMultitouchDetector = new MultitouchDetector(mMultitouchListener);
		setEGLContextClientVersion(2);
		setRenderer(mGameRenderer);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		mMultitouchDetector.onTouchEvent(event);
		return true;
	}

	@Override
	public void onPause() {
		/*
		 * Pause updater thread.
		 */
		mUpdaterThread.pause();
		super.onPause();
	}

	@Override
	public void onResume() {
		/*
		 * Reload all preferences.
		 */
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
		int simulationSpeed = Integer.parseInt(prefs.getString("simulationSpeed", "0"));
		int fadeinTimeout = Integer.parseInt(prefs.getString("fadeinTimeout", "0"));
		int fadeinDuration = Integer.parseInt(prefs.getString("fadeinDuration", "0"));
		int fadeoutDuration = Integer.parseInt(prefs.getString("fadeoutDuration", "0"));
		int colorCell = prefs.getInt("colorCell", 0);
		int colorFadein = prefs.getInt("colorFadein", 0);
		int colorBackground = prefs.getInt("colorBackground", 0);

		/*
		 * Push preferences to model.
		 */
		mGameModel.setPrefs(simulationSpeed, fadeinTimeout, fadeinDuration, fadeoutDuration,
				colorCell, colorFadein, colorBackground);

		/*
		 * Recalculate updater delta.
		 */
		long delta = Math.round(1000.0 / simulationSpeed);
		mUpdaterThread.setDelta(delta);

		super.onResume();
	}
}